home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume90 / comm / dnet / netkeys2 / part01 next >
Encoding:
Internet Message Format  |  1990-07-07  |  56.1 KB

  1. Path: xanth!cs.odu.edu!Amiga-Request
  2. From: Amiga-Request@cs.odu.edu (Amiga Sources/Binaries Moderator)
  3. Newsgroups: comp.sources.amiga
  4. Subject: v90i199: netkeys 2.0 - control two amigas via dnet, Part01/02
  5. Message-ID: <13066@xanth.cs.odu.edu>
  6. Date: 7 Jul 90 15:13:25 GMT
  7. Sender: tadguy@cs.odu.edu
  8. Reply-To: sas.UUCP!walker%sas@rti.rti.org (Doug Walker)
  9. Lines: 1743
  10. Approved: tadguy@cs.odu.edu (Tad Guy)
  11. X-Mail-Submissions-To: Amiga@cs.odu.edu
  12. X-Post-Discussions-To: comp.sys.amiga
  13.  
  14. Submitted-by: sas.UUCP!walker%sas@rti.rti.org (Doug Walker)
  15. Posting-number: Volume 90, Issue 199
  16. Archive-name: comm/dnet/netkeys-2.0/part01
  17.  
  18. [ uuencoded executables enclosed  ...tad ]
  19.  
  20. NETKEYS 2.0 is a DNET server that will let you use one mouse and
  21. keyboard to control two Amigas connected via a null modem.  Version
  22. 2.0 features the ability to simply move the mouse off one edge of
  23. the screen and onto the other Amiga's screen.  A Software Distillery
  24. project by Doug Walker.
  25.  
  26. #!/bin/sh
  27. # This is a shell archive.  Remove anything before this line, then unpack
  28. # it by saving it into a file and typing "sh file".  To overwrite existing
  29. # files, type "sh file -c".  You can also feed this as standard input via
  30. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  31. # will see the following message at the end:
  32. #        "End of archive 1 (of 2)."
  33. # Contents:  channel.h dnet.h dnetlib.c makefile mshow.c netkeys.doc
  34. #   netkeys.h nkutil.c snetkeys.c snetkeys.uu
  35. # Wrapped by tadguy@xanth on Sat Jul  7 11:13:10 1990
  36. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  37. if test -f 'channel.h' -a "${1}" != "-c" ; then 
  38.   echo shar: Will not clobber existing file \"'channel.h'\"
  39. else
  40. echo shar: Extracting \"'channel.h'\" \(1724 characters\)
  41. sed "s/^X//" >'channel.h' <<'END_OF_FILE'
  42. X
  43. X/*
  44. X *  CHANNEL.H
  45. X *
  46. X *  DNET (c)Copyright 1988, Matthew Dillon, All Rights Reserved.
  47. X *
  48. X *  Channel structures for SCMD_* channel commands.
  49. X */
  50. X
  51. X#ifndef DNET_H
  52. Xtypedef unsigned char ubyte;
  53. Xtypedef unsigned short uword;
  54. Xtypedef unsigned long ulong;
  55. Xtypedef struct MsgPort PORT;
  56. Xtypedef struct IOStdReq IOR;
  57. X#endif
  58. X
  59. X#define CSWITCH struct _CSWITCH
  60. X#define COPEN    struct _COPEN
  61. X#define CCLOSE    struct _CCLOSE
  62. X#define CACKCMD struct _CACKCMD
  63. X#define CEOFCMD struct _CEOFCMD
  64. X#define CIOCTL    struct _CIOCTL
  65. X
  66. XCSWITCH {        /*  SWITCH current data channel */
  67. X    ubyte   chanh;
  68. X    ubyte   chanl;
  69. X};
  70. X
  71. XCOPEN {         /*  OPEN port on channel    */
  72. X    ubyte   chanh;
  73. X    ubyte   chanl;
  74. X    ubyte   porth;
  75. X    ubyte   portl;
  76. X    ubyte   error;    /*  error return 0=ok        */
  77. X    ubyte   pri;
  78. X};
  79. X
  80. XCCLOSE {        /*  CLOSE a channel        */
  81. X    ubyte   chanh;
  82. X    ubyte   chanl;
  83. X};
  84. X
  85. XCACKCMD {        /*  Acknowledge an open/close        */
  86. X    ubyte   chanh;
  87. X    ubyte   chanl;
  88. X    ubyte   error;    /*  ERETRY ENOPORT ECLOSE1 ECLOSE2  */
  89. X    ubyte   filler;
  90. X};
  91. X
  92. XCEOFCMD {        /*  Send [R/W] EOF        */
  93. X    ubyte   chanh;
  94. X    ubyte   chanl;
  95. X    ubyte   flags;
  96. X    ubyte   filler;
  97. X};
  98. X
  99. XCIOCTL {
  100. X    ubyte   chanh;    /* channel            */
  101. X    ubyte   chanl;
  102. X    ubyte   cmd;    /* ioctl command        */
  103. X    ubyte   valh;    /* ioctl value            */
  104. X    ubyte   vall;
  105. X    ubyte   valaux;    /* auxillary field        */
  106. X};
  107. X
  108. X#define CIO_SETROWS    1    /* PTY's only                   */
  109. X#define CIO_SETCOLS    2    /* PTY's only                   */
  110. X#define CIO_STOP    3    /* any channel, flow control    */
  111. X#define CIO_START    4    /* any channel, flow control    */
  112. X#define CIO_FLUSH    5
  113. X
  114. X#define CHAN    struct _CHAN
  115. X
  116. XCHAN {
  117. X    PORT    *port;
  118. X    IOR     *ior;
  119. X    ubyte   state;
  120. X    ubyte   flags;
  121. X    char    pri;    /*  transmit priority    */
  122. X};
  123. X
  124. END_OF_FILE
  125. if test 1724 -ne `wc -c <'channel.h'`; then
  126.     echo shar: \"'channel.h'\" unpacked with wrong size!
  127. fi
  128. # end of 'channel.h'
  129. fi
  130. if test -f 'dnet.h' -a "${1}" != "-c" ; then 
  131.   echo shar: Will not clobber existing file \"'dnet.h'\"
  132. else
  133. echo shar: Extracting \"'dnet.h'\" \(6639 characters\)
  134. sed "s/^X//" >'dnet.h' <<'END_OF_FILE'
  135. X
  136. X/*
  137. X *  DNET.H
  138. X *
  139. X *  DNET (c)Copyright 1988, Matthew Dillon, All Rights Reserved.
  140. X *
  141. X */
  142. X
  143. X#define DNET_H
  144. X
  145. X#ifdef LATTICE
  146. X#include <exec/types.h>
  147. X#include <exec/nodes.h>
  148. X#include <exec/lists.h>
  149. X#include <exec/ports.h>
  150. X#include <exec/libraries.h>
  151. X#include <exec/devices.h>
  152. X#include <exec/io.h>
  153. X#include <exec/memory.h>
  154. X#include <exec/interrupts.h>
  155. X#include <intuition/intuition.h>
  156. X#include <devices/console.h>
  157. X#include <devices/timer.h>
  158. X#include <libraries/dos.h>
  159. X#include <libraries/dosextens.h>
  160. X#include <libraries/filehandler.h>
  161. X#include <string.h>
  162. X#include <stdlib.h>
  163. X#include <proto/exec.h>
  164. X#include <proto/dos.h>
  165. X
  166. X#define U_ARGS(a) a
  167. X
  168. X#else
  169. X
  170. X#define U_ARGS(a) ()    /* No support for prototypes - oh well */
  171. X
  172. X#endif
  173. X
  174. X
  175. Xtypedef unsigned char    ubyte;
  176. Xtypedef unsigned short    uword;
  177. Xtypedef unsigned long    ulong;
  178. X
  179. Xtypedef struct MsgPort        PORT;
  180. Xtypedef struct timerequest  IOT;
  181. Xtypedef struct IOStdReq     IOR;
  182. Xtypedef struct List        LIST;
  183. Xtypedef struct Node        NODE;
  184. Xtypedef struct Process        PROC;
  185. Xtypedef struct Message        MSG;
  186. X
  187. X#include "channel.h"
  188. X
  189. X#ifndef MAX(a,b)
  190. X#define MAX(a,b) (((a)>(b))?(a):(b))
  191. X#endif
  192. X
  193. X#define PKT struct _PKT
  194. X#define PNODE    struct _PNODE
  195. X
  196. X#define BTOC(yow)           ((ubyte *)((long)(yow) << 2))
  197. X#define DNETPORTNAME        "DNET.UNIT."
  198. X#define OFFSET(ptr,elem)    ((long)((char *)&(ptr)->elem - (char *)(ptr)))
  199. X
  200. X#define EMPTY    0    /*  empty (sent)                    */
  201. X#define READY    1    /*  data ready (not sent yet)       */
  202. X
  203. X#define MAXCHAN 128    /*  Max # of channels supported     */
  204. X#define SYNC    0xFF    /*  SYNC character            */
  205. X#define MAXPKT    200    /*  maximum packet size         */
  206. X#define MINPKT    32    /*  minimum maximum packet size
  207. X                (for priority scheme)           */
  208. X
  209. X#define OVERHEAD    7    /*  for packets with data        */
  210. X
  211. XPNODE {
  212. X    NODE    node;
  213. X    char    name[32];
  214. X    ulong   seg;
  215. X};
  216. X
  217. XPKT {
  218. X    uword   iolength;    /*  send: length of packet, recv: length of data    */
  219. X    ubyte   state;    /*  EMPTY, READY     */
  220. X
  221. X    ubyte   sync;    /*  THE PACKET        */
  222. X    ubyte   ctl;
  223. X    ubyte   cchk;
  224. X    ubyte   lenh;
  225. X    ubyte   lenl;
  226. X    ubyte   data[MAXPKT+2];
  227. X};
  228. X
  229. X/*  RECEIVER STATES    */
  230. X#define RS_SYNC 0        /*    Waiting for sync        */
  231. X#define RS_CTL    1        /*    Waiting for command        */
  232. X#define RS_CCHK 2        /*    Waiting for check byte        */
  233. X#define RS_LEN1 3        /*    Waiting for MSB length byte    */
  234. X#define RS_LEN2 4        /*    Waiting for LSB length byte    */
  235. X#define RS_DATA 5        /*    Waiting for data & checksum    */
  236. X
  237. X#define DNCMD_OPEN    32  /*    Application open        */
  238. X#define DNCMD_SOPEN    33  /*    Server open            */
  239. X#define DNCMD_CLOSE    34  /*    Close a channel         */
  240. X#define DNCMD_EOF    35  /*    Will no longer write to channel */
  241. X
  242. X#define DNCMD_WRITE    36  /*    Write data to a channel     */
  243. X#define DNCMD_QUIT    37  /*    Kill the DNET server        */
  244. X#define DNCMD_IOCTL    38
  245. X
  246. X/*  REQUEST TYPES    */
  247. X#define RTO_REQ     1   /*    Network read timeout        */
  248. X#define WTO_REQ     2   /*    Network write-ack timeout    */
  249. X#define RNET_REQ    3   /*    Network read data        */
  250. X#define WNET_REQ    4   /*    Network write data sent     */
  251. X#define PKT_REQ     5   /*    Returned packets from servers    */
  252. X#define OPEN_REQ    6
  253. X#define IGWNET_REQ    7
  254. X
  255. X/* PACKET CONTROL BYTE */
  256. X#define PKF_SEQUENCE    0xE0    /*  Sequence #            */
  257. X#define PKF_DATA    0x10    /*  1-65535 bytes        */
  258. X#define PKF_RESERVED    0x08    /*  reserved bit        */
  259. X#define PKF_MASK    0x07    /*  command mask        */
  260. X
  261. X#define PKCMD_WRITE    1    /*  A DATA packet        */
  262. X#define PKCMD_CHECK    2    /*  Request ACK or NAK for win    */
  263. X#define PKCMD_ACK    3    /*  ACK a window        */
  264. X#define PKCMD_NAK    4    /*  NAK a window        */
  265. X#define PKCMD_RESTART    5    /*  Restart            */
  266. X#define PKCMD_ACKRSTART 6    /*  Restart Acknowledge     */
  267. X#define PKCMD_RESERVE3    7
  268. X/*  CHANNEL COMMANDS    */
  269. X#define SCMD_SWITCH    0x00    /*  switch active channel #    */
  270. X#define SCMD_OPEN    0x01    /*  open a channel        */
  271. X#define SCMD_CLOSE    0x02    /*  close a channel        */
  272. X#define SCMD_ACKCMD    0x03    /*  ack an open/close request    */
  273. X#define SCMD_EOFCMD    0x04    /*  Reof or Weof        */
  274. X#define SCMD_QUIT    0x05    /*  crash dnet            */
  275. X#define SCMD_IOCTL    0x06    /*  ioctl            */
  276. X
  277. X#define SCMD_DATA    0x08    /*  stream command, DATA    */
  278. X
  279. X#define CHAN_FREE    0x01    /*  free channel        */
  280. X#define CHAN_ROPEN    0x02    /*  remote open, wait port msg    */
  281. X#define CHAN_LOPEN    0x03    /*  local open, wait reply    */
  282. X#define CHAN_OPEN    0x04
  283. X#define CHAN_CLOSE    0x05    /*  see flags            */
  284. X#define CHANF_ROK    0x01    /*  NOT read eof        */
  285. X#define CHANF_WOK    0x02    /*  remote will accept data    */
  286. X#define CHANF_LCLOSE    0x04
  287. X#define CHANF_RCLOSE    0x08
  288. X
  289. Xstruct DChannel {
  290. X    PORT    port;          /*  receive data, replies      */
  291. X    PORT    *dnetport;          /* dnet's master port          */
  292. X    LIST    rdylist;          /* ready to be read         */
  293. X    uword   chan;          /* channel # for open channels */
  294. X    ubyte   eof;          /* channel remotely closed/eof */
  295. X    ubyte   filler;
  296. X    int     qlen;          /* allowed write queue size    */
  297. X    int     queued;          /* current # packets queued    */
  298. X};
  299. X
  300. Xextern void  *ArbitrateNext();
  301. X
  302. X#ifndef NOEXT
  303. Xextern IOT Rto;            /*  Read-Timeout/reset           */
  304. Xextern IOT Wto;            /*  Write-Timeout/retry           */
  305. Xextern IOR *RNet;           /*  read-request            */
  306. Xextern IOR *WNet;           /*  write-request           */
  307. Xextern PKT Pkts[9];
  308. Xextern PKT *Raux;           /*  next packet in           */
  309. Xextern PKT *RPak[4];
  310. Xextern PKT *WPak[4];
  311. Xextern PORT *DNetPort;           /*  Remote Command/Control in       */
  312. Xextern PORT *IOSink;           /*  Return port for ALL IO       */
  313. Xextern CHAN Chan[MAXCHAN];
  314. Xextern LIST TxList;           /*  For pending DNCMD_WRITE reqs.   */
  315. Xextern LIST SvList;
  316. Xextern ubyte Rto_act;
  317. Xextern ubyte Wto_act;
  318. Xextern uword RChan;
  319. Xextern uword WChan;
  320. Xextern uword RPStart;
  321. Xextern uword WPStart;
  322. Xextern uword WPUsed;
  323. Xextern uword RState;
  324. Xextern ubyte DDebug;
  325. Xextern ubyte Restart;
  326. Xextern ubyte DeldQuit;
  327. Xextern ubyte AutoHangup;
  328. Xextern ulong NumCon;
  329. Xextern ulong WTimeoutVal;
  330. Xextern ulong RTimeoutVal;
  331. Xextern long Baud;
  332. Xextern char *HostName;        /*     The Amiga's HostName    */
  333. X
  334. Xextern ubyte RestartPkt[3];
  335. Xextern ubyte AckPkt[8][3];
  336. Xextern ubyte NakPkt[8][3];
  337. Xextern ubyte CheckPkt[8][3];
  338. X#endif
  339. X
  340. X#ifdef LATTICE
  341. X/* One #ifdef LATTICE is worth 1000 U_ARGS macros! */
  342. XPORT *DListen(uword);
  343. Xvoid DUnListen(PORT *);
  344. XPORT *DAccept(PORT *);
  345. XDNAAccept(PORT *);
  346. Xvoid DPri(struct DChannel *, int);
  347. XPORT *DOpen(char * /*host*/, uword /*portnum*/,
  348. X        char /*txpri*/, char /*rxpri*/);
  349. Xint DNRead(struct DChannel *, char *, int);
  350. Xint DRead(struct DChannel *, char *, int);
  351. Xvoid DQueue(struct DChannel *, int);
  352. XDWrite(struct DChannel *, char *, int);
  353. Xvoid DEof(struct DChannel *);
  354. Xvoid DIoctl(struct DChannel *, ubyte, uword, ubyte);
  355. Xint DQuit(char *);
  356. Xvoid DClose(struct DChannel *);
  357. Xvoid WaitMsg(IOR *);
  358. Xint WaitQueue(struct DChannel *, IOR *);
  359. X
  360. X#endif
  361. X
  362. END_OF_FILE
  363. if test 6639 -ne `wc -c <'dnet.h'`; then
  364.     echo shar: \"'dnet.h'\" unpacked with wrong size!
  365. fi
  366. # end of 'dnet.h'
  367. fi
  368. if test -f 'dnetlib.c' -a "${1}" != "-c" ; then 
  369.   echo shar: Will not clobber existing file \"'dnetlib.c'\"
  370. else
  371. echo shar: Extracting \"'dnetlib.c'\" \(10399 characters\)
  372. sed "s/^X//" >'dnetlib.c' <<'END_OF_FILE'
  373. X/*
  374. X *  DNETLIB.C
  375. X *
  376. X *  DNET (c)Copyright 1988, Matthew Dillon, All Rights Reserved.
  377. X *
  378. X *  Library Interface for DNET.
  379. X */
  380. X
  381. X#include "dnet.h"
  382. X
  383. X#include <stdio.h>
  384. X
  385. X#ifndef BUG
  386. X#define BUG(a)
  387. X#define BUGGETC
  388. X#endif
  389. X
  390. Xstatic struct DChannel *MakeChannel U_ARGS((IOR *, char *));
  391. Xstatic void DeleteChannel U_ARGS((struct DChannel *));
  392. Xstatic void FixSignal      U_ARGS((struct DChannel *));
  393. X
  394. X#define NAMELEN sizeof("DNET.PORT.XXXXX")
  395. X#define NAMEPAT "DNET.PORT.%ld"
  396. X
  397. XPORT *DListen(portnum)
  398. Xuword portnum;
  399. X{
  400. X    PORT *port;
  401. X    char *ptr;
  402. X
  403. X    port = NULL;
  404. X    ptr = AllocMem(NAMELEN, MEMF_PUBLIC);   /*  memory the the name     */
  405. X    sprintf(ptr, NAMEPAT, portnum);
  406. X    Forbid();                               /*  task-atomic operation   */
  407. X    if (FindPort(ptr) || !(port = CreatePort(ptr,0)))
  408. X       FreeMem(ptr, NAMELEN);
  409. X    Permit();
  410. X    return(port);
  411. X}
  412. X
  413. Xvoid
  414. XDUnListen(lisport)
  415. XPORT *lisport;
  416. X{
  417. X   register char *ptr;
  418. X   ptr = lisport->mp_Node.ln_Name;
  419. X
  420. X   if (lisport)
  421. X   {
  422. X      Forbid();                       /*  task-atomic operation       */
  423. X      while (DNAAccept(lisport));     /*  remove all pending requests */
  424. X      DeletePort(lisport);            /*  gone!                       */
  425. X      Permit();
  426. X      FreeMem(ptr, NAMELEN);
  427. X   }
  428. X}
  429. X
  430. X/*
  431. X *  DAccept()
  432. X *
  433. X *  Note:   This call will work even if called by a task which does not
  434. X *        own the listen port.
  435. X */
  436. X
  437. XPORT *
  438. XDAccept(lisport)
  439. XPORT *lisport;
  440. X{
  441. X    register IOR *ior;
  442. X    register struct DChannel * chan;
  443. X
  444. XBUG(("DAccept: Entry, port %lx\n", lisport))
  445. X
  446. X    chan = NULL;
  447. X    while (!chan && (ior = (IOR *)GetMsg(lisport))) {
  448. X       switch(ior->io_Command) {
  449. X      case DNCMD_SOPEN:
  450. X         BUG(("DAccept: SOPEN command\n"))
  451. X         chan = MakeChannel(ior, NULL);
  452. X         break;
  453. X      default:
  454. X         BUG(("DAccept: Unrecognized command '%d'\n", ior->io_Command))
  455. X         ior->io_Error = 1;
  456. X         break;
  457. X    }
  458. X    BUG(("DAccept: Replying\n"))
  459. X    ReplyMsg(&ior->io_Message);
  460. X    }
  461. X    BUG(("DAccept: After while loop\n"))
  462. X    if (lisport->mp_MsgList.lh_Head != (NODE *)&lisport->mp_MsgList.lh_Tail)
  463. X       SetSignal(1 << lisport->mp_SigBit, 1 << lisport->mp_SigBit);
  464. X
  465. X    return(chan ? &chan->port : NULL);
  466. X}
  467. X
  468. X/*
  469. X *  Refuse a connection
  470. X */
  471. X
  472. XDNAAccept(lisport)
  473. XPORT *lisport;
  474. X{
  475. X    IOR *ior;
  476. X
  477. X    if (ior = (IOR *)GetMsg(lisport)) {
  478. X    ior->io_Error = 1;
  479. X    ReplyMsg(&ior->io_Message);
  480. X    }
  481. X    if (lisport->mp_MsgList.lh_Head != (NODE *)&lisport->mp_MsgList.lh_Tail)
  482. X       SetSignal(1 << lisport->mp_SigBit, 1 << lisport->mp_SigBit);
  483. X    return(ior != NULL);
  484. X}
  485. X
  486. Xvoid DPri(chan, pri)
  487. Xstruct DChannel * chan;
  488. Xint pri;
  489. X{
  490. X}
  491. X
  492. X
  493. XPORT *
  494. XDOpen(host, portnum, txpri, rxpri)
  495. Xchar *host;
  496. Xchar txpri, rxpri;
  497. Xuword portnum;
  498. X{
  499. X    IOR ior;
  500. X    struct DChannel *chan;
  501. X
  502. X    if (!host)
  503. X       host = "0";
  504. X    chan = MakeChannel(&ior, host);
  505. X    if (rxpri > 126)
  506. X    rxpri = 126;
  507. X    if (rxpri < -127)
  508. X    rxpri = -127;
  509. X    if (txpri > 126)
  510. X    txpri = 126;
  511. X    if (txpri < -127)
  512. X    txpri = -127;
  513. X    if (chan->dnetport) {
  514. X    ior.io_Command = DNCMD_OPEN;
  515. X    ior.io_Unit = (void *)portnum;
  516. X    ior.io_Offset = (long)chan;
  517. X    ior.io_Message.mn_ReplyPort = &chan->port;
  518. X    ior.io_Message.mn_Node.ln_Pri = txpri;
  519. X    ior.io_Message.mn_Node.ln_Name= (char *)rxpri;
  520. X
  521. X    PutMsg(chan->dnetport, &ior.io_Message);
  522. X    WaitMsg(&ior);
  523. X    if (ior.io_Error == 0) {
  524. X       chan->chan = (long)ior.io_Unit;
  525. X       FixSignal(chan);
  526. X       return(&chan->port);
  527. X       }
  528. X    }
  529. X    DeleteChannel(chan);
  530. X    return(NULL);
  531. X}
  532. X
  533. X
  534. XDNRead(chan, buf, bytes)
  535. Xstruct DChannel * chan;
  536. Xchar *buf;
  537. Xint bytes;
  538. X{
  539. X    register IOR *ior;
  540. X    int len;
  541. X    long n;
  542. X
  543. X    len = 0;
  544. X    if (chan->eof)
  545. X       return(-1);
  546. X    while (bytes && ((ior = (IOR *)
  547. X           RemHead((struct List *)&chan->rdylist)) ||
  548. X           (ior = (IOR *)GetMsg(&chan->port)))) {
  549. X       if (ior->io_Message.mn_Node.ln_Type == NT_REPLYMSG)
  550. X       {
  551. X      if (!chan->queued)
  552. X      {
  553. X         BUG(("DNRead: Software Error"));
  554. X      }
  555. X      else
  556. X         --chan->queued;
  557. X      if (ior->io_Length)
  558. X         FreeMem((char *)ior->io_Data, (long)ior->io_Length);
  559. X     FreeMem((char *)ior, (long)sizeof(IOR));
  560. X     continue;
  561. X       }
  562. X      switch(ior->io_Command)
  563. X      {
  564. X     case DNCMD_CLOSE:
  565. X     case DNCMD_EOF:
  566. X        chan->eof = 1;
  567. X        ReplyMsg(&ior->io_Message);
  568. X        break;
  569. X
  570. X     case DNCMD_WRITE:
  571. X        n = ior->io_Length - ior->io_Actual;
  572. X        if (n <= bytes)
  573. X        {
  574. X           memcpy(buf, ((char *)ior->io_Data) + ior->io_Actual, n);
  575. X           bytes -= n;
  576. X           len += n;
  577. X           buf += n;
  578. X           ReplyMsg(&ior->io_Message);
  579. X        }
  580. X        else
  581. X        {
  582. X           memcpy(buf, (char *)ior->io_Data + ior->io_Actual, bytes);
  583. X           len += bytes;
  584. X           ior->io_Actual += bytes;
  585. X           bytes = 0;
  586. X           Forbid();   /*  DNET device is a task, no need to Disable() */
  587. X           ior->io_Message.mn_Node.ln_Type = NT_MESSAGE;
  588. X           AddHead(&chan->port.mp_MsgList, (struct Node *)ior);
  589. X           Permit();
  590. X        }
  591. X        break;
  592. X     default:
  593. X        ior->io_Error = 1;
  594. X        ReplyMsg(&ior->io_Message);
  595. X      }
  596. X    }
  597. X    FixSignal(chan);
  598. X    if (chan->eof)
  599. X       SetSignal(1 << chan->port.mp_SigBit, 1 << chan->port.mp_SigBit);
  600. X    return(len);
  601. X}
  602. X
  603. Xint DRead(chan, buf, bytes)
  604. Xchar *buf;
  605. Xstruct DChannel * chan;
  606. Xint bytes;
  607. X{
  608. X   long len;
  609. X   long n;
  610. X
  611. X   len = 0;
  612. X   if (chan->eof)
  613. X   {
  614. X      BUG(("****DNET EOF!!!\n"));
  615. X      return(-1);
  616. X   }
  617. X
  618. X   while (bytes)
  619. X   {
  620. X      WaitPort(&chan->port);
  621. X      n = DNRead(chan, buf, bytes);
  622. X      len += n;
  623. X      if (n < 0) break;
  624. X      buf += n;
  625. X      bytes -= n;
  626. X      if (chan->eof) break;
  627. X   }
  628. X   return(len);
  629. X}
  630. X
  631. Xvoid DQueue(chan, n)
  632. Xstruct DChannel * chan;
  633. Xint n;
  634. X{
  635. X    chan->qlen = n;
  636. X}
  637. X
  638. XDWrite(chan, buf, bytes)
  639. Xstruct DChannel * chan;
  640. Xchar *buf;
  641. Xint bytes;
  642. X{
  643. X    IOR tmpior;
  644. X    IOR *ior;
  645. X    int error;
  646. X
  647. X   error = bytes;
  648. X   if (chan->qlen)
  649. X   {
  650. X      if (WaitQueue(chan, NULL) >= 0)
  651. X      {
  652. X     ior = (IOR *)AllocMem(sizeof(IOR), MEMF_CLEAR|MEMF_PUBLIC);
  653. X     ior->io_Command = DNCMD_WRITE;
  654. X     ior->io_Unit = (void *)chan->chan;
  655. X     ior->io_Offset = (long)chan;
  656. X     ior->io_Message.mn_ReplyPort = &chan->port;
  657. X     ior->io_Data = (APTR)AllocMem(bytes, MEMF_PUBLIC);
  658. X     ior->io_Length = bytes;
  659. X     memcpy((char *)ior->io_Data, buf, (int)bytes);
  660. X     PutMsg(chan->dnetport, &ior->io_Message);
  661. X     ++chan->queued;
  662. X      }
  663. X      else
  664. X      {
  665. X     error = -1;
  666. X      }
  667. X   }
  668. X   else
  669. X   {
  670. X      tmpior.io_Command = DNCMD_WRITE;
  671. X      tmpior.io_Unit = (void *)chan->chan;
  672. X      tmpior.io_Offset = (long)chan;
  673. X      tmpior.io_Message.mn_ReplyPort = &chan->port;
  674. X      tmpior.io_Data = (APTR)buf;
  675. X      tmpior.io_Length = bytes;
  676. X      PutMsg(chan->dnetport, &tmpior.io_Message);
  677. X      WaitMsg(&tmpior);
  678. X      if (tmpior.io_Error)
  679. X      {
  680. X     error = -1;
  681. X     BUG(("*****DWrite: io_Error %d\n", tmpior.io_Error));
  682. X     BUGGETC
  683. X      }
  684. X   }
  685. X   FixSignal(chan);
  686. X   return(error);
  687. X}
  688. X
  689. Xvoid DEof(chan)
  690. Xstruct DChannel * chan;
  691. X{
  692. X    IOR ior;
  693. X
  694. X    ior.io_Command = DNCMD_EOF;
  695. X    ior.io_Unit = (void *)chan->chan;
  696. X    ior.io_Offset = (long)chan;
  697. X    ior.io_Message.mn_ReplyPort = &chan->port;
  698. X    PutMsg(chan->dnetport, &ior.io_Message);
  699. X    WaitMsg(&ior);
  700. X    FixSignal(chan);
  701. X}
  702. X
  703. Xvoid DIoctl(chan, cmd, val, aux)
  704. Xstruct DChannel * chan;
  705. Xubyte cmd;
  706. Xuword val;
  707. Xubyte aux;
  708. X{
  709. X    IOR ior;
  710. X
  711. X    ior.io_Command = DNCMD_IOCTL;
  712. X    ior.io_Unit = (void *)chan->chan;
  713. X    ior.io_Offset = (long)chan;
  714. X    ior.io_Message.mn_ReplyPort = &chan->port;
  715. X    ior.io_Data = (APTR)(long)((val<<16)|(aux<<8)|cmd);
  716. X    PutMsg(chan->dnetport, &ior.io_Message);
  717. X    WaitMsg(&ior);
  718. X    FixSignal(chan);
  719. X}
  720. X
  721. Xint DQuit(host)
  722. Xchar *host;
  723. X{
  724. X    IOR ior;
  725. X    char buf[sizeof(DNETPORTNAME)+32];
  726. X    PORT *replyport;
  727. X    PORT *dnetport;
  728. X
  729. X    if (!host)
  730. X    host = "0";
  731. X    sprintf(buf, "%s%s", DNETPORTNAME, host);
  732. X    if (dnetport = FindPort(buf)) {
  733. X    replyport = CreatePort(NULL, 0);
  734. X    ior.io_Command = DNCMD_QUIT;
  735. X    ior.io_Unit = 0;
  736. X    ior.io_Offset = 0;
  737. X    ior.io_Message.mn_ReplyPort = replyport;
  738. X    PutMsg(dnetport, &ior.io_Message);
  739. X    WaitMsg(&ior);
  740. X    DeletePort(replyport);
  741. X    }
  742. X    return(dnetport != NULL);
  743. X}
  744. X
  745. X
  746. Xvoid DClose(chan)
  747. Xstruct DChannel * chan;
  748. X{
  749. X    IOR ior;
  750. X    IOR *io;
  751. X
  752. XBUG(("DClose: Enter\n"))
  753. X
  754. X    ior.io_Command = DNCMD_CLOSE;
  755. X    ior.io_Unit = (void *)chan->chan;
  756. X    ior.io_Offset = (long)chan;
  757. X    ior.io_Message.mn_ReplyPort = &chan->port;
  758. X    PutMsg(chan->dnetport, &ior.io_Message);
  759. X    ++chan->queued;
  760. X    chan->qlen = 0;
  761. X    WaitQueue(chan, &ior);
  762. X    while ((io = (IOR *)RemHead((struct List *)&chan->rdylist)) ||
  763. X       (io = (IOR *)GetMsg(&chan->port))) {
  764. X    io->io_Error = 1;
  765. X    ReplyMsg(&io->io_Message);
  766. X    }
  767. X    DeleteChannel(chan);
  768. X}
  769. X
  770. Xvoid WaitMsg(ior)
  771. XIOR *ior;
  772. X{
  773. X    while (ior->io_Message.mn_Node.ln_Type != NT_REPLYMSG)
  774. X    Wait(1 << ior->io_Message.mn_ReplyPort->mp_SigBit);
  775. X    Forbid();
  776. X    Remove((struct Node *)ior);
  777. X    Permit();
  778. X}
  779. X
  780. Xint WaitQueue(chan, skipior)
  781. Xstruct DChannel * chan;
  782. XIOR *skipior;
  783. X{
  784. X    register IOR *io;
  785. X    short error;
  786. X
  787. X   error = 0;
  788. X    while (chan->queued > chan->qlen) {     /*  until done  */
  789. X    WaitPort(&chan->port);   /*  something   */
  790. X    io = (IOR *)GetMsg(&chan->port);
  791. X    if (io->io_Message.mn_Node.ln_Type == NT_REPLYMSG) {
  792. X        if (error == 0)
  793. X        error = io->io_Error;
  794. X        if (io != skipior) {
  795. X        if (io->io_Length)
  796. X            FreeMem((char *)io->io_Data, io->io_Length);
  797. X        FreeMem((char *)io, sizeof(IOR));
  798. X        }
  799. X        --chan->queued;
  800. X    } else {
  801. X        AddTail(&chan->rdylist, (struct Node *)io);
  802. X    }
  803. X    }
  804. X    return((int)error);
  805. X}
  806. X
  807. Xstatic struct DChannel *MakeChannel(ior, host)
  808. Xregister IOR *ior;
  809. Xchar *host;
  810. X{
  811. X    struct DChannel * chan;
  812. X    char buf[sizeof(DNETPORTNAME)+32];
  813. X
  814. XBUG(("MakeChannel: Entry\n"))
  815. X
  816. X    chan = (struct DChannel *)AllocMem(sizeof(struct DChannel),
  817. X                       MEMF_PUBLIC|MEMF_CLEAR);
  818. X
  819. X    /*    Name, Pri */
  820. X    chan->port.mp_Node.ln_Type = NT_MSGPORT;
  821. X    chan->port.mp_SigBit = AllocSignal(-1);
  822. X    chan->port.mp_SigTask = FindTask(NULL);
  823. X    NewList(&chan->port.mp_MsgList);
  824. X    NewList(&chan->rdylist);
  825. X    chan->chan = (long)ior->io_Unit;
  826. X    ior->io_Offset = (long)chan;
  827. X    if (host) {
  828. X       sprintf(buf, "%s%s", DNETPORTNAME, host);
  829. X    ior->io_Message.mn_ReplyPort = FindPort(buf);
  830. X    }
  831. X    chan->dnetport = ior->io_Message.mn_ReplyPort;
  832. X    return(chan);
  833. X}
  834. X
  835. Xstatic void
  836. XDeleteChannel(chan)
  837. Xstruct DChannel * chan;
  838. X{
  839. X    FreeSignal(chan->port.mp_SigBit);
  840. X    FreeMem((char *)chan, (long)sizeof(struct DChannel));
  841. X}
  842. X
  843. Xstatic void
  844. XFixSignal(chan)
  845. Xregister struct DChannel * chan;
  846. X{
  847. X    if (chan->port.mp_MsgList.lh_Head !=
  848. X         (NODE *)&chan->port.mp_MsgList.lh_Tail ||
  849. X       chan->rdylist.lh_Head != (NODE *)&chan->rdylist.lh_Tail)
  850. X    SetSignal(1 << chan->port.mp_SigBit, 1 << chan->port.mp_SigBit);
  851. X}
  852. X
  853. END_OF_FILE
  854. if test 10399 -ne `wc -c <'dnetlib.c'`; then
  855.     echo shar: \"'dnetlib.c'\" unpacked with wrong size!
  856. fi
  857. # end of 'dnetlib.c'
  858. fi
  859. if test -f 'makefile' -a "${1}" != "-c" ; then 
  860.   echo shar: Will not clobber existing file \"'makefile'\"
  861. else
  862. echo shar: Extracting \"'makefile'\" \(709 characters\)
  863. sed "s/^X//" >'makefile' <<'END_OF_FILE'
  864. X#
  865. X#
  866. X# For use with Lattice LMK.  To compile, type 'LMK'.
  867. X#
  868. X#
  869. X
  870. XLIBS   = lib:lc.lib lib:amiga.lib
  871. X
  872. XCFLAGS = -cwusf -v
  873. XLC2FLAGS = 
  874. XCLIENTOBJS = netkeys.o  nkutil.o dnetlib.o mshow.o
  875. XSERVEROBJS = snetkeys.o nkutil.o dnetlib.o mshow.o
  876. X
  877. Xall:  netkeys snetkeys
  878. X
  879. Xnetkeys: $(CLIENTOBJS)
  880. X  @echo >ram:tmp.with "from lib:cback.o $(CLIENTOBJS)"
  881. X  @assign blinkwith:
  882. X  blink with ram:tmp.with SC SD ND VERBOSE BATCH to $@ lib $(LIBS)
  883. X
  884. Xsnetkeys: $(SERVEROBJS)
  885. X  @echo >ram:tmp.with "from $(SERVEROBJS)"
  886. X  @assign blinkwith:
  887. X  blink with ram:tmp.with SC SD ND VERBOSE BATCH to $@ lib $(LIBS)
  888. X
  889. Xnetkeys.o  : netkeys.c netkeys.h dnet.h
  890. X   lc $(CFLAGS) netkeys.c
  891. Xsnetkeys.o  : snetkeys.c netkeys.h dnet.h
  892. Xnkutil.o    : nkutil.c
  893. END_OF_FILE
  894. if test 709 -ne `wc -c <'makefile'`; then
  895.     echo shar: \"'makefile'\" unpacked with wrong size!
  896. fi
  897. # end of 'makefile'
  898. fi
  899. if test -f 'mshow.c' -a "${1}" != "-c" ; then 
  900.   echo shar: Will not clobber existing file \"'mshow.c'\"
  901. else
  902. echo shar: Extracting \"'mshow.c'\" \(1595 characters\)
  903. sed "s/^X//" >'mshow.c' <<'END_OF_FILE'
  904. X/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  905. X/* |_o_o|\\ Copyright (c) 1990 The Software Distillery.  All Rights Reserved.*/
  906. X/* |. o.| || This program may not be distributed without the permission of   */
  907. X/* | .  | || the authors.                                                    */
  908. X/* | o  | ||                                                                 */
  909. X/* |  . |// Written by Doug Walker                                           */
  910. X/* ======          BBS:(919)-471-6436      VOICE:(919)-467-4764              */ 
  911. X/*                 BIX: djwalker           USENET: ...!mcnc!rti!sas!walker   */
  912. X/*                 405 B3 Gooseneck Dr, Cary, NC 27513, USA                  */
  913. X/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  914. X
  915. X/* This code shamelessly stolen from Matt Dillon's DMOUSE */
  916. X
  917. X#include "netkeys.h"
  918. X
  919. Xvoid mshow(struct GfxBase *GfxBase, UWORD *NoSprData, int on)
  920. X{
  921. X   static UWORD *SprSavePtr = NULL;
  922. X   struct copinit *ci = GfxBase->copinit;
  923. X
  924. X   if(on)
  925. X   {
  926. X      if(SprSavePtr)
  927. X      {
  928. X         ci->sprstrtup[1] = (UWORD)(((ULONG)SprSavePtr) >> 16);
  929. X         ci->sprstrtup[3] = (UWORD)(((ULONG)SprSavePtr) & 0xffff);
  930. X         SprSavePtr = NULL;
  931. X      }
  932. X   }
  933. X   else if(ci->sprstrtup[0] == 0x120 && ci->sprstrtup[2] == 0x122)
  934. X   {
  935. X      if(!SprSavePtr)
  936. X         SprSavePtr = (UWORD *)(((ULONG)ci->sprstrtup[1] << 16) | 
  937. X                                 (ULONG)ci->sprstrtup[3]);
  938. X      ci->sprstrtup[1] = (UWORD)(((ULONG)NoSprData) >> 16);
  939. X      ci->sprstrtup[3] = (UWORD)(((ULONG)NoSprData) & 0xffff);
  940. X   }
  941. X}
  942. END_OF_FILE
  943. if test 1595 -ne `wc -c <'mshow.c'`; then
  944.     echo shar: \"'mshow.c'\" unpacked with wrong size!
  945. fi
  946. # end of 'mshow.c'
  947. fi
  948. if test -f 'netkeys.doc' -a "${1}" != "-c" ; then 
  949.   echo shar: Will not clobber existing file \"'netkeys.doc'\"
  950. else
  951. echo shar: Extracting \"'netkeys.doc'\" \(8411 characters\)
  952. sed "s/^X//" >'netkeys.doc' <<'END_OF_FILE'
  953. X/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
  954. X* |_o_o|\\ Copyright (c) 1989, 1990 The Software Distillery.              *
  955. X* |. o.| ||          All Rights Reserved                                  *
  956. X* | .  | ||          Written by Doug Walker                               *
  957. X* | o  | ||          The Software Distillery                              *
  958. X* |  . |//           405 B3 Gooseneck Drive                               *
  959. X* ======             Cary, NC 27513                                       *
  960. X*                    BBS:(919)-382-8265                                   *
  961. X*                                                                        *
  962. X* USENET: ...mcnc!rti!sas!walker     PLINK: dwalker      BIX: djwalker    *
  963. X\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  964. X
  965. XNetKeys is Copyright (c) 1989, 1990 The Software Distillery.
  966. XPermission is granted to distribute programs and data in this distribution
  967. Xprovided the following conditions are met:
  968. X
  969. X   1.  All files present in the distribution package must be redistributed
  970. X       with the package, including this documentation file.  If you 
  971. X       distribute on diskette, all files must be on a single diskette.
  972. X
  973. X   2.  The distributor may charge a fee to recover distribution costs.
  974. X       The fee for diskette distribution should not be more than the cost 
  975. X       to obtain the same diskette from Fred Fish or The Software Distillery,
  976. X       whichever is greater.  Current charge from The Software Distillery
  977. X       is $6 per disk for US and Canadian distribution, $7 elsewhere, including 
  978. X       all postage and handling charges.
  979. X
  980. X   3.  The distributor agrees to cease distributing the programs and data
  981. X       involved if requested to do so by the author or any member of The 
  982. X       Software Distillery.
  983. X
  984. X------------------------------DISCLAIMER
  985. X
  986. XNeither The Software Distillery nor any of its members will be held liable for 
  987. Xany damage arising from the failure of this program to perform as described,
  988. Xor any destruction of other programs or data residing on a system 
  989. Xattempting to run the program.  While we expect no damaging errors, the 
  990. Xuser of this program uses it at his or her own risk.
  991. X
  992. X------------------------------ACKNOWLEDGEMENTS
  993. X Written in Lattice C V5.05.  Thanks to Matt Dillon for DNET!
  994. X
  995. XContributions to continue development of this and other fine products for the
  996. XAmiga may be sent to the Software Distillery at the above address.
  997. X
  998. XOther Products produced by the Software Distillery are:
  999. X   BLINK      - the Turbo-charged Alink replacement
  1000. X   HACK       - The Amiga port of the famous UNIX game
  1001. X   LARN       - Another famous UNIX game
  1002. X   MEMWATCH   - Protects your machine from random trashes
  1003. X   MEMLIB     - A library of memory debugging routines
  1004. X   MAKE       - A software development tool one shouldn't be without
  1005. X   KERMIT     - The World renown file transfer protocol brought to the Amiga
  1006. X   ICONEXEC, SETALTERNATE, SETWINDOW - Icon manipulation tools
  1007. X   TSIZE      - A short utility for determining directory sizes.
  1008. X   POPCLI     - A hotkey utility and screen blanker.
  1009. X   PICKPACKET - A tutorial program for learning about the DOS packet interface
  1010. X   NET:       - An Amiga-to-Amiga network file system running on either the 
  1011. X                parallel or serial ports with no additional hardware.
  1012. X   FILEHANDLER- An example file system written entirely in C
  1013. X   
  1014. X
  1015. XAll of these are available on our BBS.
  1016. X
  1017. X-----------------------------THE GOOD STUFF
  1018. X
  1019. XNETKEYS solves a problem that I encountered when I bought my Amiga 2000.
  1020. XNaturally, I kept my A1000 around;  therefore, I became a two-Amiga Amigoid.
  1021. XUnfortunately, I discovered it was a pain to switch keyboards and mice to
  1022. Xget from one to the other Amiga.  The solution to this is NETKEYS.  NETKEYS
  1023. Xinstalls itself in the input event chain (AHEAD of Intuition) and, on demand,
  1024. Xintercepts all keystrokes and mouse events and ships them off to the other
  1025. Xmachine.  
  1026. X
  1027. XNETKEYS uses Matt Dillon's DNET networking package.  DNET is freely redist-
  1028. Xributable, available on Fred Fish #294 and on all the major nets.  To use 
  1029. XNETKEYS effectively, you will have to have the two machines sitting next to 
  1030. Xeach other, so you should connect them with a simple null modem cable and use
  1031. Xthe following command to start DNET on both machines:
  1032. X
  1033. XRUN DNET -s -X -h0 -Z0 -P0 -m0
  1034. X
  1035. X(If you have the older version 1.x of DNET, just use RUN DNET -s).  DNET will
  1036. Xuse the baud rate you have set in preferences.  If you find NETKEYS to be
  1037. Xhanging up or acting strangely, try a lower baud rate;  I find the fastest
  1038. XI can use is 9600.  After the DNET windows come up on both machines, you 
  1039. Xshould be able to type characters into one window and see them in the other.
  1040. XSelect STARTDNET from one of the machines' menus. If the other machines' 
  1041. Xwindow does not disappear, use the QUITDNET command or the BREAK command to 
  1042. Xget the DNET window back and try it again.  DNET uses the file 
  1043. XS:DNET.SERVERS to locate server programs; you will need to add a line like
  1044. X
  1045. X9494   sys:dnet/snetkeys  ram:   ;NETKEYS server
  1046. X
  1047. Xin order for DNET to find the NETKEYS server.  Change the path to reflect
  1048. Xthe actual path of the server, but don't modify the number 9494.
  1049. X
  1050. XOnce DNET has been set up properly, move to the machine whose keyboard
  1051. Xyou would like to use.  Type 'NETKEYS'.  NetKeys detaches itself from the
  1052. XCLI, so there is no need to use RUN or RUNBACK.  Once NetKeys is installed,
  1053. Xhitting Left-Amiga-R will toggle between the two machines.  Also, moving the
  1054. Xmouse cursor off the left edge of your machine will cause it to appear on
  1055. Xthe right edge of the remote machine;  and moving it off the right edge of
  1056. Xyour screen will cause it to appear on the left edge.
  1057. X
  1058. XIf you would like to use a key other than Left-Amiga-R, you can pass a 
  1059. Xparameter of the form '0x##' where ## is the hexadecimal raw key code for the
  1060. Xkey to be used.  For example, NETKEYS 0x13 would use Left-Amiga-R, just like
  1061. Xthe default; NETKEYS 0x14 would use Left-Amiga-T, and so forth.  You can 
  1062. Xchange the key NetKeys uses after invoking it by reinvoking it with different
  1063. Xparameters.
  1064. X
  1065. XIf you want to get rid of NETKEYS, just type NETKEYS QUIT.  Other options are
  1066. Xlisted below.
  1067. X
  1068. XHave fun! 
  1069. X
  1070. X--Doug
  1071. X
  1072. X------------------------------SYNTAX GUIDE
  1073. X
  1074. XParms to NETKEYS are letters;  each stands for a word.  You can type the
  1075. Xentire keyword if you like, but netkeys will only look at the first letter.
  1076. X
  1077. XNETKEYS [0xnn] [F|S] [L|R|W] [Q]
  1078. X
  1079. X   0xnn    -   Use the key with raw hexadecimal key code 0xnn as the hotkey
  1080. X               to swap displays.
  1081. X
  1082. X   F|S     -   [F]ast (default) or [S]mooth.  When the [F]ast option is 
  1083. X               active, NETKEYS will combine multiple mouse movement events 
  1084. X               into one in order to get faster results.  When [S]mooth is 
  1085. X               selected, it will not do this.  [F]ast is the default.
  1086. X
  1087. X   [L|R|W] -   [L]eft, [R]ight or [W]rap.  If [L]eft is active, the mouse
  1088. X               cursor will exit from the left edge of the main display and
  1089. X               appear on the right edge of the slave display.  If [R]ight
  1090. X               is active, the mouse cursor will exit from the right edge of
  1091. X               the main display and appear on the left edge of the slave.  If
  1092. X               [W]rap is active, both sides of the main display will cause
  1093. X               the cursor to appear on the slave.  [W]rap is the default.
  1094. X
  1095. X   [Q]         [Q]uit.  Terminates a running NETKEYS process.
  1096. X
  1097. XIf you enter a NETKEYS command and NETKEYS is already running, the parameters
  1098. Xof the running NETKEYS command are modified.  Thus, you can change from
  1099. XFAST to SMOOTH on the fly by issuing
  1100. X
  1101. X NETKEYS FAST   ;  start up NETKEYS in FAST mode
  1102. X NETKEYS SMOOTH ;  change to SMOOTH mode
  1103. X
  1104. XRemember that NETKEYS only looks at the first character of your parameters.
  1105. XTherefore, you have exactly the same effect as the above with
  1106. X
  1107. X NETKEYS FUTILE ;  first character is 'F' = FAST
  1108. X NETKEYS STUPID ;  first character is 'S' = SMOOTH
  1109. X
  1110. X------------------------------DISTRIBUTION LIST
  1111. X
  1112. Xchannel.h                   1724
  1113. Xdnet.h                      6639
  1114. Xnkutil.c                    2509
  1115. Xnetkeys.h                   4109
  1116. Xsnetkeys.c                  5856
  1117. Xnetkeys.c                  15146
  1118. Xmakefile                     709
  1119. Xnetkeys.doc                 8409
  1120. Xsnetkeys                    5840
  1121. Xnetkeys                     9396
  1122. Xmshow.c                     1595
  1123. Xdnetlib.c                  10399
  1124. END_OF_FILE
  1125. if test 8411 -ne `wc -c <'netkeys.doc'`; then
  1126.     echo shar: \"'netkeys.doc'\" unpacked with wrong size!
  1127. fi
  1128. # end of 'netkeys.doc'
  1129. fi
  1130. if test -f 'netkeys.h' -a "${1}" != "-c" ; then 
  1131.   echo shar: Will not clobber existing file \"'netkeys.h'\"
  1132. else
  1133. echo shar: Extracting \"'netkeys.h'\" \(4109 characters\)
  1134. sed "s/^X//" >'netkeys.h' <<'END_OF_FILE'
  1135. X/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  1136. X/* |_o_o|\\ Copyright (c) 1990 The Software Distillery.  All Rights Reserved.*/
  1137. X/* |. o.| || This program may not be distributed without the permission of   */
  1138. X/* | .  | || the authors.                                                    */
  1139. X/* | o  | ||                                                                 */
  1140. X/* |  . |// Written by Doug Walker                                           */
  1141. X/* ======          BBS:(919)-471-6436      VOICE:(919)-467-4764              */ 
  1142. X/*                 BIX: djwalker           USENET: ...!mcnc!rti!sas!walker   */
  1143. X/*                 405 B3 Gooseneck Dr, Cary, NC 27513, USA                  */
  1144. X/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  1145. X#include <exec/types.h>
  1146. X#include <exec/nodes.h>
  1147. X#include <exec/lists.h>
  1148. X#include <exec/memory.h>
  1149. X#include <exec/interrupts.h>
  1150. X#include <exec/ports.h>
  1151. X#include <exec/libraries.h>
  1152. X#include <exec/io.h>
  1153. X#include <exec/tasks.h>
  1154. X#include <exec/execbase.h>
  1155. X#include <exec/devices.h>
  1156. X#include <devices/timer.h>
  1157. X#include <devices/input.h>
  1158. X#include <devices/inputevent.h>
  1159. X#include <intuition/intuitionbase.h>
  1160. X#include <libraries/dos.h>
  1161. X/*#include <graphics/gfxmacros.h>*/
  1162. X#include <hardware/custom.h>
  1163. X#include <hardware/dmabits.h>
  1164. X#include <hardware/cia.h>
  1165. X#include <resources/misc.h>
  1166. X#include <proto/dos.h>
  1167. X#include <proto/exec.h>
  1168. X/*#include <proto/intuition.h>*/
  1169. X#include <graphics/copper.h>
  1170. X#include <graphics/gfxbase.h>
  1171. X#include <proto/graphics.h>
  1172. X#include <string.h>
  1173. X
  1174. X#include "dnet.h"
  1175. X
  1176. X#define PORT_NETKEYS 9494
  1177. X
  1178. X
  1179. X
  1180. X#define NKMPNAME "NetKeys 2.0"
  1181. X#define BANNER "\x9B" "1m" NKMPNAME "\x9b" "0m by Doug Walker\n"\
  1182. X               "Copyright \xA9 1990 The Software Distillery\n"\
  1183. X               "235 Trillingham Ln, Cary NC 27513 USA\nBBS:(919)382-8265\n"
  1184. X
  1185. X#define INSTR  "Use 'NetKeys QUIT' to remove\n"\
  1186. X               "Installing, please wait...\n"
  1187. X
  1188. X#define DEFDOKEY     0x13
  1189. X#define MAXMSGS      100
  1190. X
  1191. X#define MSG(fh,st)  if(fh) Write(fh, st, strlen(st))
  1192. X
  1193. X#define IESZ  (sizeof(struct InputEvent))
  1194. X#define NKMSZ (sizeof(struct NETKEYMSG))
  1195. X
  1196. X/* Magic class to tell other side information */
  1197. X#define IECLASS_NKCONTROL    IECLASS_POINTERPOS
  1198. X
  1199. X/* Values for the 'Code' field of a IECLASS_NKCONTROL message                  */
  1200. X#define IECODE_NKHOTKEY  0x01  /* Hotkey transferred control to server         */
  1201. X#define IECODE_NKHOTQUIT 0x02  /* Hotkey ending control by server              */
  1202. X#define IECODE_NKLEFT    0x04  /* Mouse is exiting from left of handler screen */
  1203. X#define IECODE_NKRIGHT   0x08  /* Mouse is exiting from right of handler scrn  */
  1204. X
  1205. Xstruct NETKEYMSG
  1206. X{
  1207. X   struct Message m;
  1208. X   short msgtype;
  1209. X   struct InputEvent ie;   
  1210. X};
  1211. X
  1212. X/* Defines for the msgtype field */
  1213. X#define NKM_NONE    -1
  1214. X#define NKM_IEVENT   0
  1215. X#define NKM_QUIT     1
  1216. X#define NKM_CONTROL  2
  1217. X#define NKM_ACK      3
  1218. X#define NKM_HEREWEGO 4
  1219. X#define NKM_WEBEDONE 5
  1220. X
  1221. Xtypedef struct
  1222. X{
  1223. X   struct Task *buddy;
  1224. X   short dokey;
  1225. X   short state;
  1226. X   short nmsgs;
  1227. X   struct MsgPort *nkmp;
  1228. X   struct MsgPort *rtnp;
  1229. X   struct IntuitionBase *ibase;
  1230. X   short  swidth;
  1231. X   short exit;
  1232. X   int active;
  1233. X   struct DChannel *chan;
  1234. X   
  1235. X} GLOBAL_DATA;
  1236. X
  1237. X/* Defines for the global.state field */
  1238. X#define EM_SANITY -3  /* Failed sanity check - prolly too many msgs outstanding */
  1239. X#define EM_NOMEM  -2  /* Out of memory                                          */
  1240. X#define EM_QUIT   -1  /* Normal quit                                            */
  1241. X#define EM_DOIT    0  /* Keep on truckin'                                       */
  1242. X#define EM_LURK    1  /* Pass events through                                    */
  1243. X#define EM_RELURK  2  /* Start lurking immediately                              */
  1244. X
  1245. X#define NKM_HANDLER 2 /* Parms to InitDevice */
  1246. X#define NKM_SERVER  1
  1247. X
  1248. Xstruct InputEvent * __regargs myhandler(struct InputEvent *ev, GLOBAL_DATA *gptr);
  1249. X
  1250. X/* * * * * * * * * * * EXTERNAL ROUTINES * * * * * * * * * */
  1251. Xstruct IOStdReq * CreateIOReq(struct MsgPort *, int);
  1252. Xvoid DeleteIOReq(struct IOStdReq *);
  1253. X
  1254. Xvoid mshow(struct GfxBase *GfxBase, UWORD *NoSprData, int on);
  1255. END_OF_FILE
  1256. if test 4109 -ne `wc -c <'netkeys.h'`; then
  1257.     echo shar: \"'netkeys.h'\" unpacked with wrong size!
  1258. fi
  1259. # end of 'netkeys.h'
  1260. fi
  1261. if test -f 'nkutil.c' -a "${1}" != "-c" ; then 
  1262.   echo shar: Will not clobber existing file \"'nkutil.c'\"
  1263. else
  1264. echo shar: Extracting \"'nkutil.c'\" \(2509 characters\)
  1265. sed "s/^X//" >'nkutil.c' <<'END_OF_FILE'
  1266. X/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  1267. X/* |_o_o|\\ Copyright (c) 1990 The Software Distillery.  All Rights Reserved.*/
  1268. X/* |. o.| || This program may not be distributed without the permission of   */
  1269. X/* | .  | || the authors.                                                    */
  1270. X/* | o  | ||                                                                 */
  1271. X/* |  . |// Written by Doug Walker                                           */
  1272. X/* ======          BBS:(919)-471-6436      VOICE:(919)-467-4764              */ 
  1273. X/*                 BIX: djwalker           USENET: ...!mcnc!rti!sas!walker   */
  1274. X/*                 405 B3 Gooseneck Dr, Cary, NC 27513, USA                  */
  1275. X/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  1276. X#include <exec/types.h>
  1277. X#include <exec/nodes.h>
  1278. X#include <exec/lists.h>
  1279. X#include <exec/memory.h>
  1280. X#include <exec/ports.h>
  1281. X#include <exec/io.h>
  1282. X#include <proto/exec.h>
  1283. X
  1284. Xstruct IOStdReq * CreateIOReq(struct MsgPort *, int);
  1285. Xvoid DeleteIOReq(struct IOStdReq *);
  1286. X
  1287. Xstruct MsgPort * CreatePort(name, pri)
  1288. Xchar *name;
  1289. Xint pri;
  1290. X{
  1291. X   UBYTE sigbit;
  1292. X   register struct MsgPort *port;
  1293. X
  1294. X   if ((sigbit = AllocSignal(-1)) == -1)
  1295. X      return((struct MsgPort *)0);
  1296. X
  1297. X   if ((port = (struct MsgPort *)AllocMem(sizeof(struct MsgPort),
  1298. X                        MEMF_CLEAR|MEMF_PUBLIC)) == 0)
  1299. X      {
  1300. X      FreeSignal(sigbit);
  1301. X      return((struct MsgPort *) (0));
  1302. X      }
  1303. X   port->mp_Node.ln_Name = name;
  1304. X   port->mp_Node.ln_Pri = pri;
  1305. X   port->mp_Node.ln_Type = NT_MSGPORT;
  1306. X   port->mp_Flags = PA_SIGNAL;
  1307. X   port->mp_SigBit = sigbit;
  1308. X   port->mp_SigTask = (struct Task *)FindTask(0);
  1309. X   AddPort(port);
  1310. X   return(port);
  1311. X}
  1312. X
  1313. Xvoid DeletePort(port)
  1314. Xstruct MsgPort *port;
  1315. X{
  1316. XRemPort(port);
  1317. XFreeSignal(port->mp_SigBit);
  1318. XFreeMem((char *)port,sizeof(struct MsgPort));
  1319. X}
  1320. X
  1321. Xstruct IOStdReq *
  1322. XCreateIOReq(port, size)
  1323. Xstruct MsgPort *port;
  1324. Xint size;
  1325. X{
  1326. X   struct IOStdReq *ioReq;
  1327. X
  1328. X   if ((ioReq = (struct IOStdReq *)
  1329. X                AllocMem(size, MEMF_CLEAR | MEMF_PUBLIC)) != NULL)
  1330. X      {
  1331. X      ioReq->io_Message.mn_Node.ln_Type = NT_MESSAGE;
  1332. X      ioReq->io_Message.mn_Node.ln_Pri  = 0;
  1333. X      ioReq->io_Message.mn_Length       = size;
  1334. X      ioReq->io_Message.mn_ReplyPort    = port;
  1335. X      }
  1336. X   return(ioReq);
  1337. X}
  1338. X
  1339. Xvoid DeleteIOReq(ioReq)
  1340. Xstruct IOStdReq *ioReq;
  1341. X{
  1342. XioReq->io_Message.mn_Node.ln_Type = 0xff;
  1343. XioReq->io_Device = (struct Device *) -1;
  1344. XioReq->io_Unit = (struct Unit *) -1;
  1345. X
  1346. XFreeMem( (char *)ioReq, ioReq->io_Message.mn_Length);
  1347. X}
  1348. X
  1349. END_OF_FILE
  1350. if test 2509 -ne `wc -c <'nkutil.c'`; then
  1351.     echo shar: \"'nkutil.c'\" unpacked with wrong size!
  1352. fi
  1353. # end of 'nkutil.c'
  1354. fi
  1355. if test -f 'snetkeys.c' -a "${1}" != "-c" ; then 
  1356.   echo shar: Will not clobber existing file \"'snetkeys.c'\"
  1357. else
  1358. echo shar: Extracting \"'snetkeys.c'\" \(5856 characters\)
  1359. sed "s/^X//" >'snetkeys.c' <<'END_OF_FILE'
  1360. X/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  1361. X/* |_o_o|\\ Copyright (c) 1990 The Software Distillery.  All Rights Reserved.*/
  1362. X/* |. o.| || This program may not be distributed without the permission of   */
  1363. X/* | .  | || the authors.                                                    */
  1364. X/* | o  | ||                                                                 */
  1365. X/* |  . |// Written by Doug Walker                                           */
  1366. X/* ======          BBS:(919)-471-6436      VOICE:(919)-467-4764              */ 
  1367. X/*                 BIX: djwalker           USENET: ...!mcnc!rti!sas!walker   */
  1368. X/*                 405 B3 Gooseneck Dr, Cary, NC 27513, USA                  */
  1369. X/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  1370. X
  1371. X/* * * * * * * * * INCLUDE FILES * * * * * * * * * * * */
  1372. X
  1373. X#include "netkeys.h"
  1374. X#include <proto/intuition.h>
  1375. X
  1376. Xstruct DChannel *chan;
  1377. X
  1378. Xstruct MsgPort *lisport;
  1379. X
  1380. Xint InitDevice(void);
  1381. Xint TermDevice(void);
  1382. X
  1383. Xvoid _main(char *);
  1384. X
  1385. Xvoid _main(x)
  1386. Xchar *x;
  1387. X{
  1388. X   short swidth;
  1389. X   short exit;
  1390. X   int state;
  1391. X   struct Screen wbdat;
  1392. X   struct MsgPort  *inputDevPort = NULL;
  1393. X   struct IOStdReq *inputRequestBlock = NULL;
  1394. X   struct InputEvent ie;
  1395. X   struct IntuitionBase *IntuitionBase = NULL;
  1396. X   struct GfxBase *GfxBase = NULL;
  1397. X   UWORD *NoSprData = NULL;
  1398. X   ULONG rc;
  1399. X
  1400. X   if (
  1401. X       InitDevice()                                               ||
  1402. X
  1403. X       ((inputDevPort = CreatePort(0,0)) == NULL)                           ||
  1404. X
  1405. X       ((inputRequestBlock = 
  1406. X               CreateIOReq(inputDevPort, sizeof(struct IOStdReq))) == NULL) ||
  1407. X
  1408. X       !(IntuitionBase = (struct IntuitionBase *)
  1409. X                                       OpenLibrary("intuition.library", 0)) ||
  1410. X
  1411. X       !(GfxBase = (struct GfxBase *) OpenLibrary("graphics.library", 0))   ||
  1412. X
  1413. X       !(NoSprData = AllocMem(12, MEMF_PUBLIC|MEMF_CHIP|MEMF_CLEAR))        ||
  1414. X
  1415. X      OpenDevice("input.device",0,(struct IORequest *)inputRequestBlock,0))
  1416. X   {
  1417. X      goto abort;
  1418. X   }
  1419. X
  1420. X   NoSprData[0] = 0xFE00;
  1421. X   NoSprData[1] = 0xFF00;
  1422. X   
  1423. X
  1424. X   /* If we have an appropriate version of intuition, ask for info */
  1425. X   /* about the workbench screen                                   */
  1426. X   if(IntuitionBase->LibNode.lib_Version < 33
  1427. X      || !(GetScreenData((char *)&wbdat, sizeof(struct Screen), 
  1428. X                              WBENCHSCREEN, NULL)))
  1429. X   {
  1430. X      /* Either we're running on an old version of the system, or the */
  1431. X      /* GetScreenData call failed for some reason.  In either case,  */
  1432. X      /* simply assume a 640x200 screen and be done with it.          */
  1433. X      swidth  = 639;
  1434. X   }
  1435. X   else
  1436. X   {
  1437. X      /* Use the wb width, and STDSCREENHEIGHT. */
  1438. X      swidth  = wbdat.Width-1;
  1439. X   }
  1440. X
  1441. X   inputRequestBlock->io_Command = IND_WRITEEVENT;
  1442. X   inputRequestBlock->io_Flags   = 0;
  1443. X   inputRequestBlock->io_Length  = IESZ;
  1444. X   inputRequestBlock->io_Data    = (APTR)&ie;
  1445. X
  1446. X   state = 0;
  1447. X   mshow(GfxBase, NoSprData, 0);
  1448. X   while(1)
  1449. X   {
  1450. X      rc = Wait(SIGBREAKF_CTRL_C | (1 << chan->port.mp_SigBit));
  1451. X
  1452. X      if(rc & SIGBREAKF_CTRL_C)          /* Received ctrl-c */
  1453. X         goto abort;
  1454. X
  1455. X      if(DRead(chan, (char *)&ie, IESZ) != IESZ)
  1456. X         goto abort;
  1457. X
  1458. X      if(ie.ie_Class == IECLASS_NKCONTROL) /* Special 'control' record */
  1459. X      {
  1460. X         exit = ie.ie_Code;
  1461. X         if(ie.ie_Code & IECODE_NKHOTQUIT)
  1462. X         {
  1463. X            mshow(GfxBase, NoSprData, 0);
  1464. X            state = 0;
  1465. X            continue;
  1466. X         }
  1467. X
  1468. X         if(!(ie.ie_Code & IECODE_NKHOTKEY))
  1469. X         {
  1470. X            IntuitionBase->MouseX = (ie.ie_X == 0 ? swidth-1 : 1);
  1471. X            IntuitionBase->MouseY = ie.ie_Y;
  1472. X         }
  1473. X
  1474. X         state = 1;
  1475. X         mshow(GfxBase, NoSprData, 1);
  1476. X         continue;
  1477. X      }
  1478. X      else if(state == 0)
  1479. X         continue;
  1480. X
  1481. X      if(
  1482. X         ie.ie_Class == IECLASS_RAWMOUSE &&
  1483. X         (ie.ie_Qualifier & IEQUALIFIER_RELATIVEMOUSE) &&
  1484. X         ie.ie_Code == IECODE_NOBUTTON &&
  1485. X         ( 
  1486. X           (
  1487. X              (exit & IECODE_NKRIGHT)          &&
  1488. X              ie.ie_X < 0                     &&
  1489. X              IntuitionBase->MouseX == 0
  1490. X           )
  1491. X           ||
  1492. X           (
  1493. X              (exit & IECODE_NKLEFT)           &&
  1494. X              ie.ie_X > 0                     &&
  1495. X              IntuitionBase->MouseX == swidth
  1496. X           )
  1497. X         )
  1498. X        )
  1499. X      {
  1500. X         mshow(GfxBase, NoSprData, 0);
  1501. X         ie.ie_X = IntuitionBase->MouseX;
  1502. X         ie.ie_Y = IntuitionBase->MouseY;
  1503. X         ie.ie_Class = IECLASS_NKCONTROL;
  1504. X         DWrite(chan, (char *)&ie, IESZ);
  1505. X         state = 0;
  1506. X         continue;
  1507. X      }
  1508. X
  1509. X      ie.ie_NextEvent = NULL;
  1510. X      DoIO((struct IORequest *)inputRequestBlock);
  1511. X   }
  1512. X
  1513. Xabort:
  1514. X   if(IntuitionBase) CloseLibrary((struct Library *)IntuitionBase);
  1515. X
  1516. X   if(GfxBase)
  1517. X   {
  1518. X      if(NoSprData)
  1519. X      {
  1520. X         mshow(GfxBase, NoSprData, 1);
  1521. X         FreeMem(NoSprData, 12);
  1522. X      }
  1523. X      CloseLibrary((struct Library *)GfxBase);
  1524. X   }
  1525. X
  1526. X   TermDevice();
  1527. X
  1528. X   if (inputRequestBlock != NULL)
  1529. X   {
  1530. X      if (inputRequestBlock->io_Device != NULL)
  1531. X         CloseDevice((struct IORequest *)inputRequestBlock);
  1532. X      DeleteIOReq(inputRequestBlock);
  1533. X   }
  1534. X
  1535. X   if (inputDevPort != NULL)  DeletePort(inputDevPort);
  1536. X}
  1537. X
  1538. Xint InitDevice(void)
  1539. X{
  1540. X   struct MsgPort *myport;
  1541. X   struct Message *msg;
  1542. X
  1543. X   chan = NULL;
  1544. X   lisport = NULL;
  1545. X
  1546. X   myport = &(((struct Process *)FindTask(0L))->pr_MsgPort);
  1547. X   lisport = DListen(PORT_NETKEYS);
  1548. X   do
  1549. X   {
  1550. X      WaitPort(myport);
  1551. X   }
  1552. X   while(!(msg=GetMsg(myport)));
  1553. X
  1554. X   ReplyMsg(msg);
  1555. X
  1556. X   if(!lisport) return(1);
  1557. X
  1558. X   Wait(1<<lisport->mp_SigBit);
  1559. X   
  1560. X   if(!(chan = (struct DChannel *)DAccept(lisport)))
  1561. X      return(1);
  1562. X
  1563. X   return(0);
  1564. X}
  1565. X
  1566. Xint TermDevice(void)
  1567. X{
  1568. X   if(chan)
  1569. X   {
  1570. X      DClose(chan);
  1571. X      chan = NULL;
  1572. X   }
  1573. X
  1574. X   if(lisport)
  1575. X   {
  1576. X      DUnListen(lisport);
  1577. X      lisport = NULL;
  1578. X   }
  1579. X
  1580. X   return(0);
  1581. X}
  1582. X
  1583. Xvoid MemCleanup(void);
  1584. Xvoid MemCleanup(){}
  1585. END_OF_FILE
  1586. if test 5856 -ne `wc -c <'snetkeys.c'`; then
  1587.     echo shar: \"'snetkeys.c'\" unpacked with wrong size!
  1588. fi
  1589. # end of 'snetkeys.c'
  1590. fi
  1591. if test -f 'snetkeys.uu' -a "${1}" != "-c" ; then 
  1592.   echo shar: Will not clobber existing file \"'snetkeys.uu'\"
  1593. else
  1594. echo shar: Extracting \"'snetkeys.uu'\" \(8214 characters\)
  1595. sed "s/^X//" >'snetkeys.uu' <<'END_OF_FILE'
  1596. Xbegin 666 snetkeys
  1597. XM```#\P`````````"``````````$```5A````1@```^D```5A3E7^<$CG)P*1Q
  1598. XMR"M(_G0K2/YX*TC^?"M(_I8K2/Z:80`#%DJ`9@`"4D*G0J=.N@/64$\K0/Z:H
  1599. XM2H!G``(^2'@`,"\`3KH$6E!/*T#^EDJ`9P`"*$/Z`K!P`"QX``1.KOW8*T#^P
  1600. XM?$J`9P`"$$/Z`JIP`$ZN_=@K0/YX2H!G``'\<`PB/``!``-.KO\Z*T#^=$J`R
  1601. XM9P`!YD'Z`I)P`")M_I9R`$ZN_D1*@&8``=`@;?YT,+S^`#%\_P```B!M_GP,+
  1602. XM:``A`!1E&D'M_IX@/````5IR`9/)+&W^?$ZN_E9*@&8&/CP"?V`(,"W^JBX`;
  1603. XM4T<@;?Z6,7P`"P`<0B@`'G`6(4``)$'M_H`B;?Z6(T@`*'H`0J<O+?YT+RW^/
  1604. XM>$ZZ#2)/[P`,<``@;`$($"@`#W(!)`'AH@!"$``@`BQX``1.KO["*T#^<`@`9
  1605. XM``QF``$P2'@`%DAM_H`O+`$(3KH'W$_O``QR%K"!9@`!%!`M_H19`&9F/"W^$
  1606. XMAC`M_H8(```!9Q9"IR\M_G0O+?YX3KH,M$_O``QZ`&".,"W^A@@```!F'C`MZ
  1607. XM_HIF""`'2,!3@&`"<`$@;?Y\,4``1C%M_HP`1'H!2'@``2\M_G0O+?YX3KH,E
  1608. XM<D_O``Q@`/].2H5G`/]($"W^A%4`9@``@C`M_H@(```/9W8P+?Z&#$``_V9LW
  1609. XM"`8``V<0,"W^BFP*(&W^?$IH`$9G&`@&``)G4#`M_HIO2B!M_GPP*`!&L$=F(
  1610. XM/D*G+RW^="\M_GA.N@P*(&W^?#MH`$;^BCMH`$3^C!M\``3^A$AX`!9(;?Z`T
  1611. XM+RP!"$ZZ!T1/[P`8>@!@`/Z^0JW^@")M_I8L>``$3J[^.&``_JI*K?Y\9PPB;
  1612. XM;?Y\+'@`!$ZN_F)*K?YX9S1*K?YT9R)(>``!+RW^="\M_GA.N@N83^\`#")M*
  1613. XM_G1P#"QX``1.KO\N(FW^>"QX``1.KOYB80`!$$JM_I9G'B!M_I9*J``49PHB$
  1614. XM2"QX``1.KOX^+RW^EDZZ`?Q83TJM_IIG"B\M_II.N@%\6$],WT#D3EU.=6ENX
  1615. XM='5I=&EO;BYL:6)R87)Y`&=R87!H:6-S+FQI8G)A<GD``&EN<'5T+F1E=FEC,
  1616. XM90``3E7_^$CG(`*1R"E(`0@I2`$,(D@L>``$3J[^VB!`0^@`7$AX)18K2?_\8
  1617. XM3KH!LEA/*4`!#"!M__PL>``$3J[^@"!M__PL>``$3J[^C"M`__A*@&?@(FW_Y
  1618. XM^"QX``1.KOZ&2JP!#&8$<`%@+G``(&P!#!`H``]R`20!X:(@`DZN_L(O+`$,]
  1619. XM3KH"2EA/*4`!"$J`9@1P`6`"<`!,WT`$3EU.=4JL`0AG#B\L`0A.N@?T6$]"%
  1620. XMK`$(2JP!#&<.+RP!#$ZZ`<Y83T*L`0QP`$YU3G5(YP,R)F\`&"XO`!QP_RQXA
  1621. XM``1.KOZV+``,!@#_9@1P`&!(<"(B/``!``%.KO\Z)$`@"F8,<``0!DZN_K!PZ
  1622. XM`&`J)4L`"B`'%4``"15\``0`"$(J``X51@`/D\E.KO[:)4``$")*3J[^GB`*=
  1623. XM3-],P$YU2.<`$B9O``PB2RQX``1.KOZ8<``0*P`/3J[^L")+<").KO\N3-]("
  1624. XM`$YU3E7__$CG`1(F;P`8+B\`'"`'(CP``0`!+'@`!$ZN_SHK0/_\2H!G%B!`Z
  1625. XM$7P`!0`(0B@`"2(',4$`$B%+``Y,WTB`3EU.=4CG`!(F;P`,%WP`_P`(,'S_\
  1626. XM_R=(`!0G2``8<``P*P`2(DLL>``$3J[_+DS?2`!.=4Y5__A(YP$"/B\`&D*M<
  1627. XM__QP$'(!+'@`!$ZN_SIR`#('+P%(>@!J+P`K0/_X3KH/,$_O``PL>``$3J[_7
  1628. XM?")M__A.KOYZ2H!F%$*G+RW_^$ZZ_J!03RM`__Q*@&8.(FW_^'`0+'@`!$ZN)
  1629. XM_RXL>``$3J[_=B`M__Q,WT"`3EU.=41.150N4$]25"Y86%A86`!$3D54+E!/C
  1630. XM4E0N)6QD`#``1$Y%5"Y53DE4+@``)7,E<P``2.<`,B9O`!`D:P`*(`MG+"QXQ
  1631. XM``1.KO]\+PMA``"Z6$]*@&;T+PM.NOZ(6$\L>``$3J[_=B)*<!!.KO\N3-],O
  1632. XM`$YU3E7_^$CG,#*5RB`*9CX@;0`(+'@`!$ZN_HPF0"!+(`AG*C`K`!P,0``A,
  1633. XM9@Y"IR\+80`&[%!/)$!@!A=\``$`'R)++'@`!$ZN_H9@OB!M``C0_``8(FT`!
  1634. XM"")I`!2SR&<@<``@;0`($"@`#W(!)`'AHG8`%@#GH2`"+'@`!$ZN_LX@"F<$+
  1635. XM($I@`I'((`A,WTP,3EU.=4Y5__Q(YS`2)F\`'"!++'@`!$ZN_HPK0/_\2H!GN
  1636. XM#B!`$7P``0`?(D!.KOZ&0>L`&")K`!2SR&<8<``0*P`/<@$D`>&B=@`6`.>A%
  1637. XM(`).KO[.2JW__%;`1`!(@$C`3-](#$Y=3G5.50``3EU.=4Y5_\Q(YP<2)F\`/
  1638. XM4#XO`%8<+P!;&B\`7R`+9@1'^OZ,+PM(;?_080`%]E!/*T#_S')^N@%C`BH!K
  1639. XM#`4`@60">H&\`6,"+`$,!@"!9`)\@2!`2J@`(F=<.WP`(/_L<@`R!RM!_^@K:
  1640. XM0/_\*T#_WAM&_]ER`!(%*T'_VB!H`")#[?_0+'@`!$ZN_I)(;?_080`$TEA/)
  1641. XM$"W_[TH`9A@@+?_H(&W_S#%``#0O"&$`!D@@+?_,8`HO+?_,80`&%G``3.U(A
  1642. XMX/^X3EU.=4Y5__1(YS<R)F\`-"XO`#Q\`$HK`#9G!G#_8``!1$J'9P`!$D'KT
  1643. XM`"8L>``$3J[^_B1`($H@"&80($M.KOZ,)$`@2B`(9P``[G`'L"H`"&8N2JL`0
  1644. XM/&<$4ZL`/$JJ`"1G$")J`"@@*@`D+'@`!$ZN_RXB2G`P+'@`!$ZN_RY@H#`J:
  1645. XM`!P,0``D9R(,0``C9P@,0``B9@``C!=\``$`-B)*+'@`!$ZN_H9@`/]V("H`0
  1646. XM("(J`"22@"H!NH=N*B!J`"C1P"`%(FT`#&`"$MA3@&3ZGH7<A=NM``PB2BQX.
  1647. XM``1.KOZ&8`#_/"!J`"C1P"`'(FT`#&`"$MA3@&3ZW(??J@`@?@`L>``$3J[_.
  1648. XM?!5\``4`"$'K`!0B2DZN_Q!.KO]V8`#_`!5\``$`'R)*+'@`!$ZN_H9@`/[LP
  1649. XM+PMA``3T6$]**P`V9QQP`!`K``]R`20!X:)V`!8`YZ$@`BQX``1.KO[.(`9,5
  1650. XMWTSL3EU.=4CG!S(F;P`<)&\`("XO`"1\`$HK`#9G!'#_8#!*AV<J($LL>``$8
  1651. XM3J[^@"\'+PHO"V$`_F9/[P`,*@#<A4J%:PK5Q9Z%2BL`-F?2(`9,WTS@3G5(J
  1652. XMYP$0)F\`#"XO`!`G1P`X3-\(@$YU3E7_R$CG`S(F;P!4)&\`6"XO`%PL!TJKE
  1653. XM`#AG>D*G+PMA``+L4$]*@&MH<#`B/``!``$L>``$3J[_.B!`,7P`)``<<@`R5
  1654. XM*P`T(4$`&"%+`"PA2P`.*T#_S"`'<@%.KO\Z(&W_S"%``"@A1P`D(`<B2BQH$
  1655. XM`"A@`AS94X!D^B!K`"(B;?_,+'@`!$ZN_I)2JP`\8$9\_V!".WP`)/_L<``P-
  1656. XM*P`T*T#_Z"M+__PK2__>*TK_^"M'__0@:P`B0^W_T"QX``1.KOZ22&W_T&$`+
  1657. XM`?Y83THM_^]G`GS_+PMA``.`(`9,[4S`_[1.74YU3E7_T$CG`!(F;P!`.WP`8
  1658. XM(__L<``P*P`T*T#_Z"M+__PK2__>(&L`(D/M_]`L>``$3J[^DDAM_]!A``&F/
  1659. XM+HMA``,R3.U(`/_(3EU.=4Y5_]!(YP<2)F\`3!XO`%,\+P!6&B\`6SM\`";_!
  1660. XM['``,"L`-"M`_^@K2__\*TO_WG``,`9(0$)`<@`2!>&!@(%R`!('@($K0/_X+
  1661. XM(&L`(D/M_]`L>``$3J[^DDAM_]!A``$T+HMA``+`3.U(X/^\3EU.=4Y5_YQ(F
  1662. XMYP`2)F\`="`+9@1'^OI:+PM(>OI62'KZ7DAM_Z5.N@D*3^\`$$/M_Z4L>``$0
  1663. XM3J[^>BM`_YQG0D*G0J=.NOA^.WP`)?_L0JW_Z$*M__PK0/_>*T#_H"!M_YQ#W
  1664. XM[?_0+'@`!$ZN_I)(;?_080``LBZM_Z!.NOBX3^\`#$JM_YQ6P$0`2(!(P$S?J
  1665. XM2`!.74YU3E7_S$CG`!(F;P!$.WP`(O_L<``P*P`T*T#_Z"M+__PK2__>(&L`B
  1666. XM(D/M_]`L>``$3J[^DE*K`#Q"JP`X2&W_T"\+80``D%!/0>L`)BQX``1.KO[^S
  1667. XM*T#_S$J`9@X@2TZN_HPK0/_,2H!G%B!M_\P1?``!`!\B2"QX``1.KOZ&8,@O0
  1668. XM"V$``7I,[4@`_\1.74YU2.<@$B9O`!!P![`K``AG'"!K``YP`!`H``]R`20!D
  1669. XMX:(@`BQX``1.KO["8-PL>``$3J[_?")+3J[_!$ZN_W9,WT@$3G5.5?_Z2.<!'
  1670. XM,B9O`!Y^`"`K`#RPJP`X;U8@2RQX``1.KOZ`($M.KOZ,)$!P![`J``AF,$I'D
  1671. XM9@9^`!XJ`!^U[0`,9QI*J@`D9PPB:@`H("H`)$ZN_RXB2G`P3J[_+E.K`#Q@E
  1672. XMK$'K`"8B2DZN_PI@H"`'2,!,WTR`3EU.=4Y5_]!(YP`R)F\`1"1O`$AP0"(\8
  1673. XM``$``2QX``1.KO\Z($`1?``$``@K0/_\</].KOZV(&W__!%```^3R4ZN_MH@5
  1674. XM;?_\(4``$$/H`!0O"4ZZ!_P@;?_\T/P`)BZ(3KH'[EA/("L`&"!M__PQ0``T_
  1675. XM)T@`+"`*9R8O"DAZ^!1(>O@<2&W_T4ZZ!LA/[P`00^W_T2QX``1.KOYZ)T``;
  1676. XM#B!M__PA:P`.`"(@"$S?3`!.74YU2.<`$B9O``QP`!`K``\L>``$3J[^L")+Z
  1677. XM<$!.KO\N3-](`$YU2.<P$B9O`!1!ZP`8(FL`%+/(9@Q!ZP`J(FL`)K/(9QQPR
  1678. XM`!`K``]R`20!X:)V`!8`YZ$@`BQX``1.KO[.3-](#$YU``!.5?_\2.<A,"9O`
  1679. XM`!PD;P`@+B\`)"MK`";__$J'9RQ*K```9VP@+```(@!"04A!(&W__#%!``HD6
  1680. XM/```___`@C%```Z3R2E)``!@1B!M__P,:`$@``AF.@QH`2(`#&8R2JP``&86A
  1681. XM<``P*``*2$!"0'(`,B@`#H"!*4```"`*0D!(0#%```H@"@*```#__S%```Y,$
  1682. XMWPR$3EU.=4Y5_\1(YR<P)F\`7"1O`&!^`'P`>@!P`!M\`"#_^W(`*T'_]G3_(
  1683. XM*T+_\D'M_]`;0/_Q&T#__"M!_^0K0?_H*TC_S$H39T)P`!`3<AA=06LXL'L0[
  1684. XM"&;V3OL0!``C8```(``@8```%@`K8```#``M8````GX!8`Y\`6`*>@%@!AM\L
  1685. XM``'__%*+8+H0$W(PL`%F!E*+&T'_^W`JL!-F$"!20^@`!"2)*U#_]E*+8`Y(L
  1686. XM;?_V+PM.N@2$4$_7P!`3<BZP`68F4HMP*K`39A`@4D/H``0DB2M0__)2BV`.7
  1687. XM2&W_\B\+3KH$5E!/U\`0$W)LL`%F"AM\``'_\5*+8`AR:+`!9@)2BQ`;<@`2F
  1688. XM`!M`__!P,%U`:P`"5+)[``AF]$[[``0`8V```BH`<V```>@`6&```7X`>&``>
  1689. XM`7@`<&```5X`;V```0P`=6```.(`9&````)*+?_Q9PP@4D/H``0DB2`08`H@C
  1690. XM4D/H``0DB2`0*T#_[&P*<@%$K?_L*T'_Z$JM_^AG!'`M8`I*!F<$<"M@`G`@D
  1691. XM&T#_T'``$`8B+?_H@H!P`!`%@H!G"%*M_\Q2K?_D+RW_["\M_\Q.N@+F4$\KR
  1692. XM0/_(("W_\DJ`:@9R`2M!__(@+?_((BW_\I*`2.T``O_$;RX@;?_,(DC3P6`"$
  1693. XM$MA3@&3Z<``0+?_[(BW_Q"!M_\Q@`A#`4X%D^B`M__(K0/_(T:W_Y$'M_]`K)
  1694. XM2/_,2@=G``%0&WP`(/_[8``!1DHM__%G#"!20^@`!"2)(!!@"B!20^@`!"2)$
  1695. XM(!`K0/_L8`#_8DHM__%G#"!20^@`!"2)(!!@"B!20^@`!"2)(!`K0/_L2BW_3
  1696. XM_&<2(&W_S!#\`#!R`2M!_^0K2/_,+P`O+?_,3KH"0%!/*T#_R&``_R@;?``P(
  1697. XM__L@+?_R2H!J!G`(*T#_\DHM__%G#"!20^@`!"2)(!!@"B!20^@`!"2)(!`KQ
  1698. XM0/_L2BW__&<6(&W_S!#\`#`0_`!X<@(K0?_D*TC_S"\`+RW_S$ZZ`AQ03RM`Y
  1699. XM_\AP6+`M__!F`/Z^2&W_T$ZZ`5!83V``_K`@4D/H``0DB2)0*TG_S&8(0?H`W
  1700. XMW"M(_\P@;?_,2AAF_%.(D>W_S"M(_^0@+?_R2H!K*K'`;R8K0/_D8"!P`2M`]
  1701. XM_^0@4D/H``0DB2`0&T#_T$(M_]%@!G``8```C"`M_^0B+?_VLH!L"'0`*T+_&
  1702. XM]F`$D:W_]DH'9S93K?_D;1AP`"!M_\P0&"\`*TC_S"!M`!!.D%A/8.)3K?_V9
  1703. XM;4AP`!`M__LO`"!M`!!.D%A/8.A3K?_V;1)P`!`M__LO`"!M`!!.D%A/8.A3\
  1704. XMK?_D;1AP`"!M_\P0&"\`*TC_S"!M`!!.D%A/8.(@"TS?#.1.74YU``!.5?_VB
  1705. XM2.<!,"9O`!XD;P`B*VT`$/_V'AI*!V<T<"6^`&8BL!)F!%**8!HO"TAM__8OY
  1706. XM"F$`^\Q/[P`,*T#_^F<$)$!@TG``$`<O`$Z36$]@QDS?#(!.74YU2.<@,"9O^
  1707. XM`!`D2TH29R1P`!`20>P`!0@P``$(`&<*<@`2`'0@DH)@!'(`$@`4@5**8-@@Y
  1708. XM"TS?#`1.=0``````````<&$@+P`((&\`!$Y5__0B3W(*3KH!7`9!`#`2P4J``
  1709. XM9O`@"1#AO\EF^D(0D(].74YU```@+P`((&\`!$Y5__0B3R(``D$`!P9!`#`2=
  1710. XMP>:(9O`@"1#AO\EF^D(0D(].74YU```P,3(S-#4V-S@Y86)C9&5F("\`""!ON
  1711. XM``1#[P`$,@`"00`/$OL0W.B(9O(@"2(/6($0X;*)9OI"$)"!3G4@;P`$(DAR3
  1712. XM`'``+P(,$``K9P8,$``M9@)22!`8!```,&T2#```"6X,)`'E@=*"TH'2@&#F4
  1713. XM#!$`+68"1($D'R`(4X`@;P`(((&0B4YU+P<N+P`(4JP!%"`'(&P!$!#`*4@!]
  1714. XM$"X?3G5.50``2.<`,"9O`!`D;P`40JP!%"E+`1!(;0`0+PI(>O_&3KK^/B!L+
  1715. XM`1!"$"`L`11,[0P`__A.74YU2H!J```>1(!*@6H```Q$@6$``"!$@4YU80``T
  1716. XM&$2`1(%.=4J!:@``#$2!80``!D2`3G4O`DA!-`%F```B2$!(04A"-`!G```&+
  1717. XMA,$P`DA`-`"$P3`"2$(R`B0?3G4O`W80#$$`@&0```;AF5%##$$(`&0```;I3
  1718. XMF5E##$$@`&0```;EF55#2D%K```&XYE30S0`YJA(0D)"YJI(0X#!-@`P`C0#[
  1719. XM2$'$P9""9```"%-#T(%D_G(`,@-(0^>X2$#!028?)!].=2!O``0@B%B00J@`(
  1720. XM!"%(``A.=0`````#\@```^H```!&```````@("`@("`@("`H*"@H*"`@("`@H
  1721. XM("`@("`@("`@("`@($@0$!`0$!`0$!`0$!`0$!"$A(2$A(2$A(2$$!`0$!`0@
  1722. XM$(&!@8&!@0$!`0$!`0$!`0$!`0$!`0$!`0$!$!`0$!`0@H*"@H*"`@("`@("B
  1723. XM`@("`@("`@("`@("`@(0$!`0("`@("`@("`@("@H*"@H("`@("`@("`@("`@D
  1724. XM("`@("`@2!`0$!`0$!`0$!`0$!`0$(2$A(2$A(2$A(00$!`0$!`0@8&!@8&!6
  1725. XM`0$!`0$!`0$!`0$!`0$!`0$!`0$0$!`0$!""@H*"@H("`@("`@("`@("`@(":
  1726. XC`@("`@("`A`0$!`@`````````````````````````````_("E
  1727. X``
  1728. Xend
  1729. Xsize 5840
  1730. END_OF_FILE
  1731. if test 8214 -ne `wc -c <'snetkeys.uu'`; then
  1732.     echo shar: \"'snetkeys.uu'\" unpacked with wrong size!
  1733. fi
  1734. # end of 'snetkeys.uu'
  1735. fi
  1736. echo shar: End of archive 1 \(of 2\).
  1737. cp /dev/null ark1isdone
  1738. MISSING=""
  1739. for I in 1 2 ; do
  1740.     if test ! -f ark${I}isdone ; then
  1741.     MISSING="${MISSING} ${I}"
  1742.     fi
  1743. done
  1744. if test "${MISSING}" = "" ; then
  1745.     echo You have unpacked both archives.
  1746.     rm -f ark[1-9]isdone
  1747. else
  1748.     echo You still need to unpack the following archives:
  1749.     echo "        " ${MISSING}
  1750. fi
  1751. ##  End of shell archive.
  1752. exit 0
  1753. -- 
  1754. Mail submissions (sources or binaries) to <amiga@cs.odu.edu>.
  1755. Mail comments to the moderator at <amiga-request@cs.odu.edu>.
  1756. Post requests for sources, and general discussion to comp.sys.amiga.
  1757.